"""
对接佰翔的 http 请求接口
"""

import os, sys

parent_path = os.path.abspath(os.path.join(__file__, *([".."] * 4)))
sys.path.insert(0, parent_path)

from core.utils.logger import logging

import yaml
import json, requests

from enum import Enum, unique


@unique
class CameraType(Enum):
    kIr = "ir"
    kWide = "wide"
    kZoom = "zoom"


@unique
class ResetMode(Enum):
    kInTheMiddle = "0"
    kDown = "1"


@unique
class FocusMode(Enum):
    kMF = 0
    kAFS = 1
    kAFC = 2


class HttpMessage:
    def init_cfg(self, cfg_path):
        # 读取配置文件
        if isinstance(cfg_path, str):
            with open(cfg_path, "r") as f:
                cfg = yaml.safe_load(f)
                self.init(**cfg)

    def init(self, ip, port, user, passwd, dock_sn, uav_sn, payload_index, timeout=20):
        self.__http_prefix = "http://" + ip + ":" + str(port) + "/"
        self.__user = user
        self.__passwd = passwd
        self.__timeout = timeout
        self.__dock_sn = dock_sn
        self.__uav_sn = uav_sn
        self.__payload_index = payload_index

        json_data = {
            "username": self.__user,
            "password": self.__passwd,
        }
        token_url = self.__http_prefix + "api/User/login"

        # 获取 token
        request = requests.post(
            url=token_url, json=json_data, timeout=self.__timeout, verify=False
        )
        # logging.info(f"{request.text}")
        response_json = json.loads(request.text)
        if response_json["code"] == 200:
            self.__token = {"UAV-Token": response_json["token"]}
            logging.info(self.__token)
        else:
            raise Exception("Http login fail")

    def flight_authority_grab(self):
        """
        飞行控制权抢夺
        """

        url = self.__http_prefix + "drc/flightauthoritygrab?sn=" + self.__dock_sn
        response = requests.get(
            url,
            headers=self.__token,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            # logging.info("payload_authority_grab success")
            return True
        else:
            # logging.error("payload_authority_grab fail")
            return False

    def payload_authority_grab(self):
        """
        负载控制权抢夺
        """

        url = (
            self.__http_prefix
            + "camera/payloadauthoritygrab?sn="
            + self.__dock_sn
            + "&payload_index="
            + self.__payload_index
        )
        response = requests.get(
            url,
            headers=self.__token,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            # logging.info("payload_authority_grab success")
            return True
        else:
            # logging.error("payload_authority_grab fail")
            return False

    def camera_aim(self, camera_type: CameraType, x, y):
        """
        负载控制-双击成为 AIM
        """

        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "camera_type": camera_type.value,
            "locked": False,
            "x": x,
            "y": y,
        }
        url = self.__http_prefix + "camera/cameraaim"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def camera_frame_zoom(self, camera_type: CameraType, x, y, width, height):
        """
        负载控制-框选变焦
        """

        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "camera_type": camera_type.value,
            "locked": False,
            "x": x,
            "y": y,
            "w": width,
            "h": height,
        }
        url = self.__http_prefix + "camera/cameraframezoom"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def camera_focal_length_set(self, camera_type: CameraType, zoom_factor):
        """
        负载控制-变焦
        """

        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "camera_type": camera_type.value,
            "zoom_factor": zoom_factor,  # 2~200 2~20
        }

        url = self.__http_prefix + "camera/camerafocallengthset"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def gimbal_reset(self, reset_mode: ResetMode):
        """
        负载控制—重置云台
        """

        url = (
            self.__http_prefix
            + "camera/gimbalreset?sn="
            + self.__dock_sn
            + "&payload_index="
            + self.__payload_index
            + "&reset_mode="
            + reset_mode.value
        )
        response = requests.get(
            url,
            headers=self.__token,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def live_lens_change(self, camera_type: CameraType):
        """
        设置直播镜头
        """
        json_data = {
            "pid": self.__dock_sn,
            "video_id": self.__uav_sn
            + "/"
            + self.__payload_index
            + "/zoom-0",  # 该相机级别的视频源可以选择的码流索引
            "video_type": camera_type.value,
        }
        url = self.__http_prefix + "live/live_lens_change"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def live_stop(self):
        """
        关闭无人机直播推流
        """
        json_data = {
            "pid": self.__dock_sn,
            "video_id": self.__uav_sn
            + "/"
            + self.__payload_index
            + "/normal-0",  # 该相机级别的视频源可以选择的码流索引
        }
        url = self.__http_prefix + "live/liveStop"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def flighttask_pause(self):
        """
        航线暂停
        """
        json_data = {
            "sn": self.__dock_sn,
        }
        url = self.__http_prefix + "job/flighttaskpause?sn=" + self.__dock_sn
        response = requests.get(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def flighttask_recovery(self):
        """
        航线恢复
        """
        json_data = {
            "sn": self.__dock_sn,
        }
        url = self.__http_prefix + "job/flighttaskrecovery?sn=" + self.__dock_sn
        response = requests.get(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def get_recovery_camera(self):
        """
        负载恢复
        """
        json_data = {
            "sn": self.__dock_sn,
        }
        # http://218.94.155.86:3301/job/getRecoveryCamera?docksn=7CTDM2100BYT9N&subsn=1581F6Q8D242S00C047P
        url = (
            self.__http_prefix
            + "job/getRecoveryCamera?docksn="
            + self.__dock_sn
            + "&subsn="
            + self.__uav_sn
        )
        response = requests.get(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def get_recovery_camera_pitch(self):
        """
        负载恢复-无偏航版本
        """
        json_data = {
            "sn": self.__dock_sn,
        }
        # http://218.94.155.86:3301/job/getRecoveryCamera?docksn=7CTDM2100BYT9N&subsn=1581F6Q8D242S00C047P
        url = (
            self.__http_prefix
            + "job/getRecoveryCameraPitch?docksn="
            + self.__dock_sn
            + "&subsn="
            + self.__uav_sn
        )
        response = requests.get(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def camera_screen_drag(self, pitch_speed):
        """
        负载控制-画面拖动控制
        """
        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "pitch_speed": pitch_speed,
            "yaw_speed": 0,
        }
        url = self.__http_prefix + "camera/camerascreendrag"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def camera_point_focus_action(self, camera_type: CameraType, x, y):
        """
        负载控制-点对焦
        """
        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "camera_type": camera_type.value,
            "x": x,
            "y": y,
        }
        url = self.__http_prefix + "camera/camerapointfocusaction"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False

    def camera_focus_mode_set(self, camera_type: CameraType, focus_mode: FocusMode):
        """
        负载控制-相机对焦模式设置
        """
        json_data = {
            "pid": self.__dock_sn,
            "payload_index": self.__payload_index,
            "camera_type": camera_type.value,
            "focus_mode": focus_mode.value,
        }
        url = self.__http_prefix + "camera/camerafocusmodeset"
        response = requests.post(
            url,
            headers=self.__token,
            json=json_data,
            timeout=self.__timeout,
            verify=False,
        )

        # logging.info(response.text)
        if response.status_code == 200:
            return True
        else:
            return False


if __name__ == "__main__":
    logging.info("test")

    http_message = HttpMessage()

    http_message.init(
        ip="218.94.155.86",
        port=3301,
        user="uavadmin",
        passwd="bxkj@2024",
        dock_sn="7CTDM2100BYT9N",
        uav_sn="1581F6Q8D249300GUR00",
        payload_index="81-0-0",
    )
    # logging.info(http_message.flight_authority_grab())
    # logging.info(http_message.payload_authority_grab())

    # 空中可用
    # logging.info(http_message.camera_aim(CameraType.kZoom, 0.5, 0.6))
    # logging.info(http_message.camera_aim(CameraType.kWide, 0.4, 0.5))
    # logging.info(http_message.camera_frame_zoom(CameraType.kZoom, 0.2, 0.2, 0.2, 0.2))

    # 地面可用
    # logging.info(http_message.camera_focal_length_set(CameraType.kZoom, 1))
    # logging.info(http_message.live_lens_change(CameraType.kWide))
    # logging.info(http_message.gimbal_reset(ResetMode.kDown))
    # logging.info(http_message.gimbal_reset(ResetMode.kInTheMiddle))

    # 航线中可用
    # logging.info(http_message.flighttask_pause())
    # logging.info(http_message.flighttask_recovery())
    # logging.info(http_message.get_recovery_camera())
    # logging.info(http_message.camera_screen_drag(-20))
    # logging.info(http_message.camera_point_focus_action(CameraType.kZoom, 0.5, 0.5))
    # logging.info(http_message.camera_focus_mode_set(CameraType.kZoom, FocusMode.kAFS))
